package com.mybatisplus.mp.lock;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;

/**
 * 单体应用使用本地锁就能解决缓存击穿
 */
@Component
public class LocalLock {
    @Resource
    private StringRedisTemplate template;

    public String localLockTest(String key) {
        ValueOperations<String, String> ops = template.opsForValue();
        // 如果缓存不存在，则查询数据库
        if (StringUtils.isEmpty(ops.get(key))) {
            //多个请求同时进来
            System.out.println("缓存不存在。。。");
            String fromDB = getFromDB(key);
            return fromDB;
        }
        return ops.get(key);
    }

    public String getFromDB(String key) {
        // 如果刚开始时，多个请求同个上面的缓存判断进来，还需要去缓存确认，不然就直接查数据库了
        synchronized (this) {
            if (StringUtils.isEmpty(template.opsForValue().get(key))) {
                System.out.println("查询数据库");
                //在锁中就要把缓存放进去，不然锁不上
                template.opsForValue().set(key, "test");
                return "test";
            } else {
                return template.opsForValue().get(key);
            }
        }
    }

}
